package com.iqiju.guagua.photo.wx.mini.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iqiju.guagua.photo.wx.mini.common.Results;
import com.iqiju.guagua.photo.wx.mini.mapper.WxUserPhotoMapper;
import com.iqiju.guagua.photo.wx.mini.model.WxMiniApp;
import com.iqiju.guagua.photo.wx.mini.model.WxMiniUser;
import com.iqiju.guagua.photo.wx.mini.model.WxUserPhoto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class WxUserPhotoService extends ServiceImpl<WxUserPhotoMapper, WxUserPhoto> {

    private static final String IMG_SEC_CHECK = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=ACCESS_TOKEN";


    @Autowired
    private IDService idService;

    @Autowired
    private FastDFSService fastDFSService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private WxUserPhotoService wxUserPhotoService;

    @Autowired
    private WxMiniAppService wxMiniAppService;

    @Autowired
    private WxMiniUserService wxMiniUserService;

    @Autowired
    private RestTemplate restTemplate;

    public Results<Integer> upload(MultipartFile file, String id, String wxMiniAppId, String no) {
        if (file == null){
            log.error("上传文件为空！");
            return Results.paramError("上传文件为空");
        }
        if (id == null||id.trim().length()<=0){
            log.error("参数id为空！");
            return Results.paramError("参数id不能为空");
        }

        if (wxMiniAppId == null||wxMiniAppId.trim().length()<=0){
            log.error("参数wxMiniAppId为空！");
            return Results.paramError("参数wxMiniAppId不能为空");
        }
        if (no == null||no.trim().length()<=0){
            log.error("参数no为空！");
            return Results.paramError("参数no不能为空");
        }

        WxMiniApp wxMiniApp = wxMiniAppService.selectById(Long.parseLong(wxMiniAppId));
        if (wxMiniApp == null){
            log.error("小程序id {} 不存在！", wxMiniAppId);
            return Results.paramError("小程序id "+wxMiniAppId+" 不存在");
        }
        wxMiniUserService.setAccessToken(wxMiniApp);



        if (!restCheckPic(file,wxMiniApp.getAccessToken())){
            log.warn("图片检测违规！");
            return new Results(87014,"图片检测违规",null);
        }







        String filename = null;
        try {
            filename = fastDFSService.upload(file);
        } catch (Exception e) {
            e.printStackTrace();
            return Results.error("上传图片失败");
        }
        log.info("上传文件全路径 = {}", filename);
        WxUserPhoto wxUserPhoto = new WxUserPhoto();
        wxUserPhoto.setId(idService.id());
        wxUserPhoto.setCreateTime(new Date());
        wxUserPhoto.setNo(Integer.parseInt(no));
        wxUserPhoto.setWxMiniAppId(Long.parseLong(wxMiniAppId));
        wxUserPhoto.setUrl(filename);
        wxUserPhoto.setUserTemplateId(Long.valueOf(id));

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        log.info("当前用户信息");
        log.info("{}",JSON.toJSONString(principal));
        log.info("上传文件唯一id={}",id);

        WxMiniUser wxMiniUser = JSON.parseObject(JSON.toJSONString(principal), WxMiniUser.class);
        wxUserPhoto.setUserId(wxMiniUser.getId());
        if(save(wxUserPhoto)){
            return new Results<>(Results.SUCCESS_CODE,Results.SUCCESS_MSG,1);
        }
        return new Results<>(Results.SUCCESS_CODE,Results.SUCCESS_MSG,0);
    }

    private Boolean restCheckPic(MultipartFile file, String accessToken) {
        String url = IMG_SEC_CHECK.replace("ACCESS_TOKEN",accessToken);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        param.add("media",file.getResource());
        org.springframework.http.HttpEntity<MultiValueMap<String, Object>> httpEntity = new org.springframework.http.HttpEntity<>(param, headers);

        JSONObject checkImgObject = null;
        String errcode = null;
        try {
            ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url, httpEntity, JSONObject.class);
            checkImgObject = responseEntity.getBody();
            errcode = checkImgObject.getString("errcode");
            log.info("图片验证结果===={}",checkImgObject);
        } catch (Throwable e) {
            log.error("====图片检测违规url访问异常======");
            log.error(e.getMessage(), e);
            return true;
        }

        if ("0".equals(errcode)){
            log.info("图片检测不违规！");
            return true;
        }else if("87014".equals(errcode)){
            log.warn("图片检测违规！");
            return false;
        }else{
            log.error("图片违规检测发生未知异常");
            return true;
        }
    }


    public List<WxUserPhoto> selectListByUserTemplateId(String userTemplateId){
        String key = getUserTemplateKey(userTemplateId);
        String userPhotoArray = stringRedisTemplate.opsForValue().get(key);
        List<WxUserPhoto> wxUserPhotos = null;
        if (userPhotoArray!=null&&userPhotoArray.trim().length()>0){
            wxUserPhotos = JSON.parseArray(userPhotoArray, WxUserPhoto.class);
            return wxUserPhotos;
        }
        QueryWrapper<WxUserPhoto> wxUserPhotoQueryWrapper = new QueryWrapper<>();
        wxUserPhotoQueryWrapper.eq("user_template_id",userTemplateId);
        wxUserPhotos = list(wxUserPhotoQueryWrapper);
        stringRedisTemplate.opsForValue().set(key,JSON.toJSONString(wxUserPhotos),30, TimeUnit.DAYS);
        return wxUserPhotos;
    }

    private String getUserTemplateKey(String userTemplateId){
        return "GUAGUA_PHOTO_USER_TEMPLATE_"+userTemplateId;
    }



    public Results<String> change(String userTemplateId, String wxMiniAppId, String no) {
        if (userTemplateId == null || userTemplateId.trim().length()<=0){
            log.error("userTemplateId为空！");
            return Results.paramError("参数userTemplateId为空");
        }
        Long tempId = null;
        try {
            tempId = Long.valueOf(userTemplateId);
        } catch (Exception e) {
            log.error("userTemplateId=[{}] 转换为long异常！",userTemplateId);
            log.error(e.getMessage(), e);
            return Results.paramError("参数userTemplateId=["+userTemplateId+"] 不合法");
        }
        if (userTemplateId == null || userTemplateId.trim().length()<=0){
            log.error("userTemplateId为空！");
            return Results.paramError("参数userTemplateId为空");
        }
        Long miniId = null;
        try {
            miniId = Long.valueOf(wxMiniAppId);
        } catch (Exception e) {
            log.error("wxMiniAppId=[{}] 转换为long异常！",wxMiniAppId);
            log.error(e.getMessage(), e);
            return Results.paramError("wxMiniAppId=["+wxMiniAppId+"] 不合法");
        }

        WxMiniApp wxMiniApp = wxMiniAppService.selectById(miniId);
        if (wxMiniApp == null){
            log.error("小程序id {} 不存在！", wxMiniAppId);
            return Results.paramError("小程序id "+wxMiniAppId+" 不存在");
        }

        Integer noNum = null;
        try {
            noNum = Integer.valueOf(no);
        } catch (Exception e) {
            log.error("no=[{}] 转换为int异常！",no);
            log.error(e.getMessage(), e);
            return Results.paramError("no=["+no+"] 不合法");
        }

        QueryWrapper<WxUserPhoto> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_template_id",tempId);
        queryWrapper.orderByDesc("create_time");
        List<WxUserPhoto> list = wxUserPhotoService.list(queryWrapper);
        if (list.isEmpty()){
            log.error("参数userTemplateId=[{}]不合法，不存在此用户相册",tempId);
            return Results.paramError("参数userTemplateId=["+userTemplateId+"] 不合法  不存在此用户相册");
        }
        WxUserPhoto wxUserPhoto = list.get(0);

        wxUserPhoto.setId(idService.id());
        wxUserPhoto.setCreateTime(new Date());
        wxUserPhoto.setUserTemplateId(idService.id());
        wxUserPhoto.setWxMiniAppId(miniId);
        wxUserPhoto.setNo(noNum);
        wxUserPhotoService.save(wxUserPhoto);

        return Results.success(String.valueOf(wxUserPhoto.getUserTemplateId()));
    }
}
